{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Python包管理和虚拟环境"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 包管理\n",
    "安装第三方包的方法：\n",
    "\n",
    "1.  通过Python社区开发的 **pip** 等工具\n",
    "2.  使用系统本身自带的包管理器（ **yum** ， **apt** 等）\n",
    "3.  通过源码安装（<code>python setup.py install</code>）\n",
    "\n",
    "第三方包主要分布在 **The Python Package Index** （<https://pypi.org>）官方仓库（Python包索引，简称 **PyPI** ）以及Github、Bitbucket等代码托管服务上。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 使用 **pip**\n",
    "**pip** 是一个用来安装和管理Python包的工具。\n",
    "\n",
    "-   已经内置到Python 2.7.9和Python 3.4及其以上的版本里。\n",
    "-   支持二进制包使用wheel格式（文件名后缀是 **.whl** ）。\n",
    "-   能非常好地支持虚拟环境工具 **virtualenv** 。\n",
    "-   支持多种版本工具格式的包的下载和安装。\n",
    "-   集中管理项目以来列表（文件名一般叫作 **requirements.txt** ），使用<code>-r</code>选项安装这些依赖。\n",
    "\n",
    "如果系统中没有安装 pip，可以使用如下命令来安装：\n",
    "\n",
    "```sh\n",
    "# Ubuntu\n",
    "sudo apt install python3-pip -yq\n",
    "```\n",
    "\n",
    "系统自带的pip版本比较低，可使用pip的自更新来升级：\n",
    "\n",
    "```sh\n",
    "sudo pip install pip -U -q\n",
    "\n",
    "pip --version\n",
    "```\n",
    "\n",
    "On Windows:\n",
    "\n",
    "```sh\n",
    "python -m pip install -U pip\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### pip常用命令\n",
    "-   install: 安装包\n",
    "-   uninstall: 卸载已安装的包\n",
    "-   list: 列出已安装的包\n",
    "-   show: 显示已安装包的信息\n",
    "-   search: 在 PyPI 上搜索包\n",
    "-   freeze: 以 requirements 格式输出已安装的包\n",
    "-   check: 检查验证包依赖\n",
    "-   config: 管理本地和全局配置"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 虚拟环境\n",
    "-   不同项目之间使用不同版本的某些包，因为某些原因（比如依赖冲突）不能升级到最新版本\n",
    "-   所有的包共用一个目录，很容出现一不小心更新了项目A的依赖，却影响了项目B用的依赖的情况\n",
    "\n",
    "对环境进行隔离，使用虚拟环境让全局的 **site-packages** 目录非常干净和可管理。\n",
    "\n",
    "Python自带的 **venv** 模块和Python社区中的 **virtualenv** 都可以创建和管理虚拟环境。这些工具可用来创建一个单独、干净的Python环境，可以把所需要的包安装到各自孤立的环境中。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### venv\n",
    "创建一个Python环境：\n",
    "\n",
    "```sh\n",
    "> python -m venv /path/to/new/virtual/environment\n",
    "# On windows:\n",
    "# python -m venv c:\\path\\to\\myenv\n",
    "```\n",
    "\n",
    "激活虚拟环境：\n",
    "\n",
    "| 平台    | Shell           | 用于激活虚拟环境的命令                 |\n",
    "|---------|-----------------|----------------------------------------|\n",
    "| POSIX   | bash/zsh        | `$ source <venv>/bin/activate`         |\n",
    "|         | fish            | `$ . <venv>/bin/activate.fish`         |\n",
    "|         | csh/tcsh        | `$ source <venv>/bin/activate.csh`     |\n",
    "|         | PowerShell Core | `$ <venv>/bin/Activate.ps1`            |\n",
    "| Windows | cmd.exe         | `C:\\\\> <venv>\\Scripts\\activate.bat`    |\n",
    "|         | PowerShell      | `PS C:\\\\> <venv>\\Scripts\\Activate.ps1` |\n",
    "\n",
    "无需专门激活一个虚拟环境，可以直接调用虚拟环境下的Python解释器。\n",
    "\n",
    "**deactivate** 虚拟环境：\n",
    "\n",
    "直接在shell中使用<code>deactivate</code>命令就可以取消激活虚拟环境。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### [virtualenv](https://pypi.org/project/virtualenv/)\n",
    "\n",
    "```sh\n",
    "> pip install virtualenv\n",
    "```\n",
    "\n",
    "创建一个Python环境：\n",
    "\n",
    "```sh\n",
    "> virtualenv myenv\n",
    "# python -m venv /path/to/new/virtual/environment\n",
    "# On windows:\n",
    "# python -m venv c:\\path\\to\\myenv\n",
    "```\n",
    "\n",
    "virtualenv默认会创建一个包含了Python可执行文件、常用的标准库、激活virtualenv环境的脚本的目录。\n",
    "\n",
    "使用source激活virtualenv环境：\n",
    "\n",
    "```sh\n",
    "> source venv/bin/activate\n",
    "\n",
    "(myenv)> which python\n",
    "# 注意终端提示的改变，前面添加了“(myenv)”前缀。\n",
    "```\n",
    "\n",
    "退出虚拟环境，取消激活：\n",
    "\n",
    "```sh\n",
    "(myenv)> deactivate\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Virtualenvwrapper\n",
    "virtualenvwrapper是对virtualenv的功能拓展，它有如下用途：\n",
    "\n",
    "-   用来管理全部的虚拟环境\n",
    "-   能方便地创建、删除和拷贝虚拟环境\n",
    "-   用单个命令即可切换不同的虚拟环境\n",
    "-   可以用<code>Tab</code>补全虚拟环境\n",
    "-   支持用户粒度的钩子支持\n",
    "\n",
    "#### 安装\n",
    "\n",
    "```sh\n",
    "# installation\n",
    "pip3 install virtualenvwrapper\n",
    "```\n",
    "\n",
    "#### 初始化\n",
    "\n",
    "```sh\n",
    "export WORKON_HOME=~/.virtualenvs\n",
    "mkdir -p $WORKON_HOME\n",
    "source /usr/local/bin/virtualenvwrapper.sh\n",
    "```\n",
    "\n",
    "将环境变量添加进<code>.bashrc</code>，这样每次登录时就自动初始化了。\n",
    "\n",
    "初始化时给系统添加了一些虚拟环境相关的函数，比如用来创建虚拟环境的<code>mkvirtualenv</code>：\n",
    "\n",
    "```sh\n",
    "> mkvirtualenv -p python3.6 jupyter_env3\n",
    "(jupyter_env3)> deactivate  # 退出虚拟环境的命令还是一样的\n",
    "```\n",
    "\n",
    "<code>mkvirtualenv</code>还会添加如下5个项目级别的钩子模板：\n",
    "\n",
    "| 模板              | 用途                                                                                                  |\n",
    "|-------------------|-------------------------------------------------------------------------------------------------------|\n",
    "| `predeactivate`   | 在虚拟环境取消激活之前执行。                                                                          |\n",
    "| `postdeactivate`  | 在虚拟环境取消激活之后执行。                                                                          |\n",
    "| `preactivate`     | 在虚拟环境激活之前执行。                                                                              |\n",
    "| `postactivate`    | 在虚拟环境激活之后执行。                                                                              |\n",
    "| `get_env_details` | 使用 `lsvirtualenv` / `showvirtualenv` 等命令时，对于当前环境的额外钩子，可以添加虚拟环境介绍等内容。 |\n",
    "\n",
    "使用<code>Tab</code>管理虚拟环境：\n",
    "\n",
    "```sh\n",
    "> workon <Tab>  # 输入workon，然后按Tab\n",
    "\n",
    "> workon jupyter_env3  # 直接使用workon就可以激活或者切换虚拟环境\n",
    "```\n",
    "\n",
    "### 其它常用的命令\n",
    "\n",
    "| 命令             | 作用                                                                  |\n",
    "|------------------|-----------------------------------------------------------------------|\n",
    "| `lsvirtualenv`   | 列出全部的虚拟环境                                                    |\n",
    "| `showvirtualenv` | 列出单个虚拟环境的信息                                                |\n",
    "| `rmvirtualenv`   | 删除一个虚拟环境                                                      |\n",
    "| `cpvirtualenv`   | 拷贝虚拟环境                                                          |\n",
    "| `allvirtualenv`  | 对当前虚拟环境执行统一的命令，e.g. `allvirtualenv pip install flake8` |\n",
    "| `cdvirtualenv`   | 直接切换到虚拟环境的子目录里面，e.g. `cdvirtualenv bin`               |\n",
    "| `cdsitepackages` | 和 `cdvirtualenv` 同理，切换到虚拟环境的 `site-packages` 目录下       |\n",
    "| `lssitepackages` | 列出 `site-packages` 目录下的目录                                     |\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conda\n",
    "\n",
    "[Conda](https://docs.conda.io/en/latest/) 一个使用Python语言开发的开源（基于BSD许可证发布）跨平台语言无关的包管理与环境管理系统。\n",
    "其允许用户方便地安装不同版本的二进制软件包与该计算平台需要的所有库。还允许用户在不同版本的包之间切换、从一个软件仓库下载包并安装。\n",
    "\n",
    "特性：\n",
    "\n",
    "-   支持多种语言的包管理，最重要的是可以解决包依赖问题\n",
    "-   支持语言包括Python、R、Ruby、Lua、Scala、Java、JavaScript、C/C++、FORTRAN等\n",
    "-   支持在Windows、macOS和Linux上运行\n",
    "-   可以构建不同的环境，并对环境进行保存、加载和切换操作\n",
    "-   包含在所有版本的Anaconda和Miniconda中\n",
    "\n",
    "一些基于Conda的工具软件：\n",
    "\n",
    "-   [Bioconda](https://bioconda.github.io/)，用于计算生物学\n",
    "-   Anaconda\n",
    "-   Miniconda\n",
    "-   [Anaconda Repository](https://repo.anaconda.com/)\n",
    "\n",
    "查看是否已经安装成功，显示conda版本号：\n",
    "\n",
    "```sh\n",
    "conda --version\n",
    "# conda 4.7.12\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 常用命令\n",
    "\n",
    "1.  更新conda\n",
    "\n",
    "    ```sh\n",
    "    conda update conda\n",
    "    ```\n",
    "\n",
    "    如果新的conda版本可用，可以输入<code>y</code>进行更新：\n",
    "\n",
    "        Proceed ([y]/n)? y\n",
    "\n",
    "2.  创建一个新的环境并在其中来安装包\n",
    "\n",
    "    开始使用conda时，已经有了一个默认的环境，命名为<code>base</code>。\n",
    "\n",
    "    先面的命令使用Python 3.6版本创建一个名为<code>snowflakes</code>的环境并在其中安装<code>biopython</code>这个包。\n",
    "\n",
    "    ```sh\n",
    "    conda create --name snowflakes biopython python=3.6\n",
    "    ```\n",
    "\n",
    "    conda 将检查BioPython依赖关系，提问你是否继续，输入<code>y</code>并按回车执行。\n",
    "\n",
    "3.  激活环境\n",
    "\n",
    "    ```sh\n",
    "    conda activate snowflakes  # conda 4.6+\n",
    "    ```\n",
    "\n",
    "4.  取消激活环境\n",
    "\n",
    "    ```sh\n",
    "    conda deactivate\n",
    "    ```\n",
    "\n",
    "5.  列出所有环境\n",
    "\n",
    "    ```sh\n",
    "    conda info --envs\n",
    "    ```\n",
    "\n",
    "6.  切换回默认环境（<code>base</code>）\n",
    "\n",
    "    ```sh\n",
    "    conda activate\n",
    "    ```\n",
    "\n",
    "7.  完整删除一个环境\n",
    "\n",
    "    ```sh\n",
    "    conda remove --name ENVNAME --all\n",
    "    ```\n",
    "\n",
    "8.  更新一个环境中的所有包\n",
    "\n",
    "    ```sh\n",
    "    conda update --all --name ENVNAME\n",
    "    ```\n",
    "\n",
    "9.  删除一个环境中某个包\n",
    "\n",
    "    ```sh\n",
    "    conda uninstall PKGNAME --name ENVNAME\n",
    "    ```\n",
    "\n",
    "10. 导出一个环境中的已安装的包\n",
    "\n",
    "    ```sh\n",
    "    conda list --explicit > pkgs.txt\n",
    "    ```\n",
    "\n",
    "11. 使用导出的包管理文件创建一个环境\n",
    "\n",
    "    ```sh\n",
    "    conda create --name NEWNEV --file pkgs.txt\n",
    "    ```\n",
    "\n",
    "更多内容请参考[官方手册](https://docs.conda.io/projects/conda/en/latest/user-guide/index.html)。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  },
  "name": "python-pkg-env-management.ipynb",
  "toc": {
   "colors": {
    "hover_highlight": "#DAA520",
    "running_highlight": "#FF0000",
    "selected_highlight": "#FFD700"
   },
   "moveMenuLeft": true,
   "nav_menu": {
    "height": "248.352px",
    "width": "251.989px"
   },
   "navigate_menu": true,
   "number_sections": false,
   "sideBar": true,
   "threshold": 4,
   "toc_cell": false,
   "toc_section_display": "block",
   "toc_window_display": false,
   "widenNotebook": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
